﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Text;
using System.Net.Browser;
using System.Threading;
using System.Collections.Generic;

namespace WebRequestHelper
{
    public sealed class WebRequest
    {
        private SynchronizationContext syncContext;

        /// <summary>
        /// 
        /// </summary>
        public event GetResponseCompletedEventHandler GetResponseCompleted;



        //AsyncCallback a;


        public Dictionary<string, string> PostValues
        {
            get { return this.webRequestState.PostData; }
            //private set { this.webRequestState.PostData = value; }
        }


        /// <summary>
        /// Gets or sets the method for the request.
        /// </summary>
        /// <returns>
        /// The request method to use to contact the Internet resource. The default value is GET.
        /// </returns>
        public WebRequestMethod Method
        {
            get { return this.webRequestState.Method; }
            //set { this.webRequestState.Method = value; }
        }

        /// <summary>
        /// Gets or sets the value of the Content-type HTTP header.
        /// </summary>
        /// <returns>
        /// The value of the Content-type HTTP header. The default value is text/xml.
        /// </returns>
        public string ContentType { get; set; }

        private WebRequestState webRequestState;

        /// <summary>
        /// The private constructor :)
        /// </summary>
        private WebRequest()
        {

        }




        /// <summary>
        /// Initializes a new WebRequestHelper.WebRequest instance for the specified URI scheme.
        /// </summary>
        /// <param name="url">The URI that identifies the Internet resource.</param>
        /// <returns>A WebRequestHelper.WebRequest descendant for the specific URI scheme.</returns>
        public static WebRequest Create(String url)
        {
            return WebRequest.Create(WebRequestMethod.GET, url, null);
        }
        /// <summary>
        /// Initializes a new WebRequestHelper.WebRequest instance for the specified URI scheme with state information.
        /// </summary>
        /// <param name="url">The URI that identifies the Internet resource.</param>
        /// <param name="userState">An object containing state information for this asynchronous request.</param>
        /// <returns>A WebRequestHelper.WebRequest descendant for the specific URI scheme.</returns>
        public static WebRequest Create(String url, object userState)
        {
            return WebRequest.Create(WebRequestMethod.GET, url, null, userState);
        }


        /// <summary>
        /// Initializes a new WebRequestHelper.WebRequest instance for the specified URI scheme with callback delegate.
        /// </summary>
        /// <param name="url">The URI that identifies the Internet resource.</param>
        /// <param name="callback">The callback delegate which will be invoked when all the response is received.</param>
        /// <returns>A WebRequestHelper.WebRequest descendant for the specific URI scheme.</returns>
        public static WebRequest Create(String url, GetResponseCompletedEventHandler callback)
        {
            return WebRequest.Create(WebRequestMethod.GET, url, null, callback);
        }
        /// <summary>
        /// Initializes a new WebRequestHelper.WebRequest instance for the specified URI scheme with callback delegate and state information.
        /// </summary>
        /// <param name="url">The URI that identifies the Internet resource.</param>
        /// <param name="callback">The callback delegate which will be invoked when all the response is received.</param>
        /// <param name="userState">An object containing state information for this asynchronous request.</param>
        /// <returns>A WebRequestHelper.WebRequest descendant for the specific URI scheme.</returns>
        public static WebRequest Create(String url, GetResponseCompletedEventHandler callback, object userState)
        {
            return WebRequest.Create(WebRequestMethod.GET, url, null, callback, userState);
        }


        /// <summary>
        /// Initializes a new WebRequestHelper.WebRequest instance for the specified URI scheme with HttpWebRequest Method as POST.
        /// </summary>
        /// <param name="url">The URI that identifies the Internet resource.</param>
        /// <param name="postData">The data to write to request stream.</param>
        /// <returns>A WebRequestHelper.WebRequest descendant for the specific URI scheme.</returns>
        public static WebRequest Create(String url, Dictionary<String, String> postData)
        {
            return WebRequest.Create(WebRequestMethod.POST, url, postData);
        }
        /// <summary>
        /// Initializes a new WebRequestHelper.WebRequest instance for the specified URI scheme with HttpWebRequest Method as POST and state information.
        /// </summary>
        /// <param name="url">The URI that identifies the Internet resource.</param>
        /// <param name="postData">The data to write to request stream.</param>
        /// <param name="userState">An object containing state information for this asynchronous request.</param>
        /// <returns>A WebRequestHelper.WebRequest descendant for the specific URI scheme.</returns>
        public static WebRequest Create(String url, Dictionary<String, String> postData, object userState)
        {
            return WebRequest.Create(WebRequestMethod.POST, url, postData, userState);
        }


        /// <summary>
        /// Initializes a new WebRequestHelper.WebRequest instance for the specified URI scheme with HttpWebRequest Method as POST and a callback delegate.
        /// </summary>
        /// <param name="url">The URI that identifies the Internet resource.</param>
        /// <param name="postData">The data to write to request stream.</param>
        /// <param name="callback">The callback delegate which will be invoked when all the response is received.</param>
        /// <returns>A WebRequestHelper.WebRequest descendant for the specific URI scheme.</returns>
        public static WebRequest Create(String url, Dictionary<String, String> postData, GetResponseCompletedEventHandler callback)
        {
            return WebRequest.Create(WebRequestMethod.POST, url, postData, callback);
        }
        /// <summary>
        /// Initializes a new WebRequestHelper.WebRequest instance for the specified URI scheme with HttpWebRequest Method as POST and callback delegate and state information.
        /// </summary>
        /// <param name="url">The URI that identifies the Internet resource.</param>
        /// <param name="postData">The data to write to request stream.</param>
        /// <param name="callback">The callback delegate which will be invoked when all the response is received.</param>
        /// <param name="userState">An object containing state information for this asynchronous request.</param>
        /// <returns>A WebRequestHelper.WebRequest descendant for the specific URI scheme.</returns>
        public static WebRequest Create(String url, Dictionary<String, String> postData, GetResponseCompletedEventHandler callback, object userState)
        {
            return WebRequest.Create(WebRequestMethod.POST, url, postData, callback, userState);
        }



        private static WebRequest Create(WebRequestMethod method, String url, Dictionary<String, String> postData)
        {
            WebRequest webRequest = new WebRequest();
            webRequest.webRequestState = new WebRequestState(method, url, postData);
            return webRequest;
        }
        private static WebRequest Create(WebRequestMethod method, String url, Dictionary<String, String> postData, object userState)
        {
            WebRequest webRequest = new WebRequest();
            webRequest.webRequestState = new WebRequestState(method, url, postData, userState);
            return webRequest;
        }
        private static WebRequest Create(WebRequestMethod method, String url, Dictionary<String, String> postData, GetResponseCompletedEventHandler callback)
        {
            WebRequest webRequest = new WebRequest();
            webRequest.webRequestState = new WebRequestState(method, url, postData, callback);
            return webRequest;
        }
        private static WebRequest Create(WebRequestMethod method, String url, Dictionary<String, String> postData, GetResponseCompletedEventHandler callback, object userState)
        {
            WebRequest webRequest = new WebRequest();
            webRequest.webRequestState = new WebRequestState(method, url, postData, callback, userState);
            return webRequest;
        }












        public void GetResponseAsync()
        {
            try
            {

                syncContext = SynchronizationContext.Current;

                if (this.webRequestState != null)
                {

                    // Create request
                    HttpWebRequest request = System.Net.WebRequest.Create(this.webRequestState.RequestUri) as HttpWebRequest;

                    //request.Headers["x-custom-header"] = "value";
                    request.Method = this.webRequestState.Method.ToString();

                    this.webRequestState.Request = request;

                    switch (this.webRequestState.Method)
                    {
                        case WebRequestMethod.POST:
                            {
                                // Make async call for request stream.  Callback will be called on a background thread.
                                IAsyncResult asyncResult = request.BeginGetRequestStream(new AsyncCallback(RequestStreamCallback), this.webRequestState);
                            }
                            break;
                        case WebRequestMethod.GET:
                        default:
                            {
                                IAsyncResult asyncResult = request.BeginGetResponse(new AsyncCallback(GetRequestCompleted), this.webRequestState);
                            }
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                this.OnWebRequestFailed(ex);
            }
        }

        private void RequestStreamCallback(IAsyncResult ar)
        {
            try
            {
                WebRequestState tr = ar.AsyncState as WebRequestState;

                HttpWebRequest request = tr.Request;
                request.ContentType = String.IsNullOrEmpty(this.ContentType) ? "text/xml" : this.ContentType;

                if (tr.PostData != null && tr.PostData.Count > 0)
                {
                    Stream requestStream = request.EndGetRequestStream(ar);

                    using (StreamWriter streamWriter = new StreamWriter(requestStream))
                    {
                        foreach (var item in tr.PostData)
                        {
                            streamWriter.Write("{0}={1}&", item.Key, System.Windows.Browser.HttpUtility.UrlEncode(item.Value));
                        }
                    }
                }

                //streamWriter.Encoding = Encoding.UTF8;
                //streamWriter.Write("<?xml version=\"1.0\"?><entry xmlns=\"http://www.w3.org/2005/Atom\">" +
                //                   "<author>"
                //                   + "<name>Elizabeth Bennet</name>"
                //                   + "<email>liz@gmail.com</email>"
                //                   + "</author><title type=\"text\">Entry 1</title>" + "<content type=\"text\">This is my entry</content>"
                //                   + "</entry>");

                //streamWriter.Close();

                // Make async call for response.  Callback will be called on a background thread.
                request.BeginGetResponse(new AsyncCallback(ResponseCallback), tr);

            }
            catch (Exception ex)
            {
                this.OnWebRequestFailed(ex);
            }
        }

        private void ResponseCallback(IAsyncResult ar)
        {
            try
            {
                // get the webrequest state from AsyncState
                WebRequestState tr = ar.AsyncState as WebRequestState;

                // get the request from webRequest State
                HttpWebRequest request = tr.Request; //ar.AsyncState as HttpWebRequest;

                // get the response from request
                tr.Response = request.EndGetResponse(ar) as HttpWebResponse;

                // Invoke response onto UI thread
                syncContext.Post(ExtractResponse, tr);
            }
            catch (Exception ex)
            {
                this.OnWebRequestFailed(ex);
            }
        }

        private void ExtractResponse(object state)
        {
            try
            {
                WebRequestState tr = state as WebRequestState;

                HttpWebResponse response = tr.Response; //state as HttpWebResponse;

                string resultString = string.Empty;

                // read the response of the request.
                using (StreamReader streamReader1 = new StreamReader(response.GetResponseStream()))
                {
                    resultString = streamReader1.ReadToEnd();
                }

                // create the event args to send back through the callback delegate.
                GetResponseCompletedEventArgs webRequestCompletedEventArgs = new GetResponseCompletedEventArgs(
                        resultString,
                        null,
                        false,
                        tr.UserState
                    );

                // invoke the callback delegate
                if (tr.Callback != null)
                {
                    tr.Callback.DynamicInvoke(new object[] { webRequestCompletedEventArgs });
                }

                // invoke the WebRequestCompleted event handler
                this.OnWebRequestCompleted(webRequestCompletedEventArgs);
            }
            catch (Exception ex)
            {
                this.OnWebRequestFailed(ex);
            }
        }

        private void GetRequestCompleted(IAsyncResult ar)
        {
            try
            {
                WebRequestState tr = (WebRequestState)ar.AsyncState;

                HttpWebResponse response = (HttpWebResponse)tr.Request.EndGetResponse(ar);

                tr.Response = response;

                string resultString = string.Empty;

                // read the response of the request.
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    resultString = reader.ReadToEnd();
                }


                // create the event args to send back through the callback delegate.
                GetResponseCompletedEventArgs webRequestCompletedEventArgs = new GetResponseCompletedEventArgs(
                        resultString,
                        null,
                        false,
                        tr.UserState
                    );

                // invoke the callback delegate
                if (tr.Callback != null)
                {
                    tr.Callback.DynamicInvoke(new object[] { webRequestCompletedEventArgs });
                }

                // invoke the WebRequestCompleted event handler
                this.OnWebRequestCompleted(webRequestCompletedEventArgs);
            }
            catch (Exception ex)
            {
                this.OnWebRequestFailed(ex);
            }
        }
        





        private void OnWebRequestFailed(Exception ex)
        {
            GetResponseCompletedEventArgs webRequestCompletedEventArgs = new GetResponseCompletedEventArgs(
                    null,
                    ex,
                    false,
                    null
                );

            this.OnWebRequestCompleted(webRequestCompletedEventArgs);
        }

        private void OnWebRequestCompleted(GetResponseCompletedEventArgs e)
        {
            if (this.GetResponseCompleted != null)
            {
                this.GetResponseCompleted(e);
            }
        }

    }


    
   

    [Obsolete("Dont use this class now")]
    internal sealed class HttpWebRequestHelper22222
    {

        [Obsolete("Dont Use It Now", true)]
        private void WebC()
        {
            System.Uri uri = new Uri("http://api.twitter.com/1/statuses/user_timeline/sohailabid.xml");
            WebClient client = new WebClient();
            //client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            //client.DownloadStringAsync(uri);


            client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
            client.OpenReadAsync(uri);
        }

        [Obsolete("Dont Use It Now", false)]
        private void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {

            //String t = e.Result;
        }

        [Obsolete("Dont Use It Now", false)]
        private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {

            String t = e.Result;
        }


        [Obsolete("Dont Use It Now", true)]
        private void download()
        {
            String message = String.Empty;
            System.Uri uri = new Uri("http://api.twitter.com/1/statuses/user_timeline/sohailabid.xml");

            try
            {





                //HttpWebRequest httpwebrequest = (HttpWebRequest)WebRequest.Create(uri);

                HttpWebRequest httpwebrequest = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(uri);

                httpwebrequest.AllowReadStreamBuffering = false;
                //httpwebrequest.BeginGetResponse(new AsyncCallback(DownloadRespCallback), httpwebrequest);
            }
            catch (Exception e)
            {
                message = "Exception!\n";
                message += "\nMessage: ";
                message += e.Message;
                message += "\n";
                //downloadButton.IsEnabled = true;
                //uploadButton.IsEnabled = true;
            }
        }

        [Obsolete("Dont Use It Now", true)]
        private void DownloadRespCallback(IAsyncResult asynchronousResult)
        {
            String message = String.Empty;
            try
            {
                HttpWebRequest httpwebrequest = (HttpWebRequest)asynchronousResult.AsyncState;
                HttpWebResponse response = (HttpWebResponse)httpwebrequest.EndGetResponse(asynchronousResult);
                Stream responsestream = response.GetResponseStream();
                BinaryReader reader = new BinaryReader(responsestream);
                bool endofstream = false;

                while (!endofstream)
                {
                    try
                    {
                        string responsestring = reader.ReadString();


                        message += responsestring;

                    }
                    catch (Exception)
                    {
                        endofstream = true;
                    }
                }
            }
            catch (Exception e)
            {

                message += "Exception!\n";
                message += "\nMessage: ";
                message += e.Message;
                message += "\n";

            }
        }




        [Obsolete("Dont Use It Now", true)]
        private void RequestTimelineFromTwitterAPI()
        {
            HttpWebRequest request = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new System.Uri("http://api.twitter.com/1/statuses/user_timeline/sohailabid.xml"));
            request.Method = "GET";

            request.BeginGetResponse(new AsyncCallback(TimelineRequestCompleted), request);
        }


        [Obsolete("Dont Use It Now", false)]
        private void TimelineRequestCompleted(IAsyncResult ar)
        {
            HttpWebRequest request = (HttpWebRequest)ar.AsyncState;

            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);

            string TwitterJSON;

            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                TwitterJSON = reader.ReadToEnd();
            }

            //List<twitterstatus> StatusCollection = JSONHelper<list><twitterstatus>>.ConvertJsonStringToObject(TwitterJSON);

            //this.Dispatcher.BeginInvoke(() => CallInvokeStuff(StatusCollection));
        }


        //        function anmelden(user) {
        ////  base 64 =U2lsdmVybGlnaHRJbnNpOnBhc3N3b3Jk
        //    var w = new Sys.Net.WebRequest();
        //    w.set_url("http://twitter.com/statuses/friends_timeline/61248865.rss");
        //    w.set_httpVerb("GET");
        //    w.get_headers()["Authorization"] = "Basic " + user;
        //    w.add_completed(WennFertig);
        //    w.invoke();
        //}


        //private static void R()
        //{
        //    String outputBlock = String.Empty;
        //    try
        //    {

        //        System.Uri uri = new Uri("http://www.contoso.com");
        //        // Create a HttpWebrequest object to the desired URL.
        //        HttpWebRequest myHttpWebRequest1 = (HttpWebRequest)WebRequest.Create(uri);

        //        // Create an instance of the RequestState and assign the previous myHttpWebRequest1
        //        // object to it's request field.  
        //        RequestState myRequestState = new RequestState();
        //        myRequestState.Request = myHttpWebRequest1;


        //        // Start the asynchronous request.
        //        IAsyncResult result =
        //          (IAsyncResult)myHttpWebRequest1.BeginGetResponse(new AsyncCallback(RespCallback), myRequestState);

        //        //allDone.WaitOne();

        //        // Release the HttpWebResponse resource.
        //        myRequestState.Response.Close();
        //    }
        //    catch (WebException e)
        //    {

        //        outputBlock += "\nException raised!\n";
        //        outputBlock += "Message: ";
        //        outputBlock += e.Message;
        //        outputBlock += "\nStatus: ";
        //        outputBlock += e.Status;
        //        outputBlock += "\n";
        //    }
        //    catch (Exception e)
        //    {
        //        outputBlock += "\nException raised!\n";
        //        outputBlock += "\nMessage: ";
        //        outputBlock += e.Message;
        //        outputBlock += "\n";
        //    }


        //}


        //private static void RespCallback(IAsyncResult asynchronousResult)
        //{
        //    try
        //    {
        //        // State of request is asynchronous.
        //        RequestState myRequestState = (RequestState)asynchronousResult.AsyncState;
        //        HttpWebRequest myHttpWebRequest2 = myRequestState.request;
        //        myRequestState.response = (HttpWebResponse)myHttpWebRequest2.EndGetResponse(asynchronousResult);

        //        // Read the response into a Stream object.
        //        Stream responseStream = myRequestState.response.GetResponseStream();
        //        myRequestState.streamResponse = responseStream;

        //        // Begin the Reading of the contents of the HTML page and print it to the console.
        //        IAsyncResult asynchronousInputRead = responseStream.BeginRead(myRequestState.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);
        //    }
        //    catch (WebException e)
        //    {
        //        // Need to handle the exception
        //    }
        //}
        //private static void ReadCallBack(IAsyncResult asyncResult)
        //{
        //    try
        //    {

        //        RequestState myRequestState = (RequestState)asyncResult.AsyncState;
        //        Stream responseStream = myRequestState.StreamResponse;
        //        int read = responseStream.EndRead(asyncResult);
        //        // Read the HTML page and then do something with it
        //        if (read > 0)
        //        {
        //            myRequestState.RequestData.Append(Encoding.UTF8.GetString(myRequestState.ReBuffer, 0, read));
        //            IAsyncResult asynchronousResult = responseStream.BeginRead(myRequestState.ReBuffer, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);
        //        }
        //        else
        //        {
        //            if (myRequestState.RequestData.Length > 1)
        //            {
        //                string stringContent;
        //                stringContent = myRequestState.RequestData.ToString();
        //                // do something with the response stream here
        //            }

        //            responseStream.Close();
        //            //allDone.Set();

        //        }

        //    }
        //    catch (WebException e)
        //    {
        //        // Need to handle the exception
        //    }

        //}


    }
}
